/**
 * @file Tracker.h
 * @author enemy1205 (enemy1205@qq.com)
 * @brief 追踪器基类头文件
 * @date 2021-10-03
 */
#pragma once

#include "Features.h"
#include "KalmanFilterX.hpp"
#include "Parameter.h"
#include "Math.h"

using cv::Point2f;

class Tracker {
public:
    Tracker();

    //更新特征序列
    virtual void update(const Features_ptr &) {};

    // 获取目标特征
    inline Features_ptr getGoalFeature() { return this->features_sequence.front(); }

    //返回特征序列
    inline deque<Features_ptr> getFeatures() { return this->features_sequence; }

    //获取序列匹配信息
    inline bool getMatchMessage() const { return isTrackerMatched; }

    //设置序列匹配信息
    inline void setMatchMessage(bool _match) { this->isTrackerMatched = _match; }

    //获取pnp信息
    ResultPnP getPnp() { return this->pnp_data; }

    //设置pnp信息
    ResultPnP &setPnp() { return this->pnp_data; }

    // 目标装甲板灯条是否出现闪烁
    inline bool isShine() const { return vanish_num > 0; }

    //返回预测中心点(绘图用)
    Point2f getPredictedCenter() { return predicted_center; }

    //返回云台预测角(发送数据)
    Point2f getPredictedAngle() { return predicted_angle; }

    //返回预测中心点(绘图用)
    Point2f &setPredictedCenter() { return predicted_center; }

    //返回云台预测角(发送数据)
    Point2f &setPredictedAngle() { return predicted_angle; }

    //返回卡尔曼初始化标志位
    bool getKalmanInfo() { return this->kalmanInited; }

    //返回距离卡尔曼初始化标志位
    bool getDisKalmanInfo() { return this->kalmanInited_dis; }

    //设置卡尔曼初始化标志位
    bool &setKalmanInfo() { return this->kalmanInited; }

    //设置距离卡尔曼初始化标志位
    bool &setDisKalmanInfo() { return this->kalmanInited_dis; }

    //设置距离卡尔曼滤波器
    auto &setDistanceKF() { return this->KF_Dis; }

    //设置装甲板卡尔曼滤波器
    auto &setArmorKF() { return this->KF_Armor; }

    //设置神符卡尔曼滤波器
    auto &setRuneKF() { return this->KF_Rune; }

    // 判断是否消失
    inline bool isVanished(uint8_t &mode) const {
        if (mode == 0) return this->vanish_num > strategyParam.NORMAL_TRACK_FRAMES;
        else return this->vanish_num > strategyParam.SENTRY_TRACK_FRAMES;
    };

    //匹配时判断是否发生突变
    virtual bool isSuddenChange(Features_ptr &to_be_matched, float &delta) = 0;

protected:
    //------------匹配参数--------------
    std::deque<Features_ptr> features_sequence;//特征时间序列
    bool isTrackerMatched;      // 当前序列是否已经匹配 (每帧重置)
    int vanish_num;        // 消失帧数
    //------------预测参数值-----------
    bool kalmanInited;          // 卡尔曼是否初始化
    bool kalmanInited_dis;      // 距离卡尔曼是否初始化
    KalmanFilterX<2, 2> KF_Rune;    // 神符卡尔曼滤波器
    KalmanFilterX<4, 4> KF_Armor;   // 装甲板卡尔曼滤波器
    KalmanFilterX<2, 2> KF_Dis;     // 距离卡尔曼滤波器
    Point2f predicted_center;   // 图像中的预测点
    Point2f predicted_angle;    // 云台预测角度
    ResultPnP pnp_data;         //PNP 信息
};

using tracker_ptr = std::shared_ptr<Tracker>;